#include <iostream>
#include <unistd.h>
#include <cassert>
#include <vector>
#include <sys/wait.h>
using namespace std;
#include "execution.hpp"
#define COUNT 3
Task t;
static int Count=0;
class Pipefd
{
public:
    Pipefd(int fd, int pid)
        : write_fd(fd),
          _pid(pid)
    {
        char buf[64];
        snprintf(buf,sizeof(buf),"我是子进程%d,我的fd:%d,我的pid：%d",cnt++,fd,pid);
        _name=buf;
    }

    int write_fd;
    int _pid;
    string _name;
    static int cnt;
};
int Pipefd::cnt=0;

void WaitCommand()
{
    while (1)
    {
        int command;
        int ret = read(0, &command, sizeof(int));
        if (ret == sizeof(int))
        {
            t.Executive(command);
        }
        else if (ret == 0)
        {
            cout<<"父进程让我："<<getpid()<<"结束"<<endl;
            break;
        }
        else
        {
            break;
        }
    }
}

void Create(vector<Pipefd> &v)
{

    // 父进程写，子进程读
    for (int i = 0; i < COUNT; i++)
    {
        int pipefd[2] = {0};
        int ret = pipe(pipefd);
        assert(ret == 0);
        pid_t pid = fork();
        if (pid == 0)
        {
            // 子进程
            close(pipefd[1]);   // 关闭不必要的fd
            dup2(pipefd[0], 0); // 我们期望，所有的子进程读取“指令"的时候，都从标准输入读取
            WaitCommand();

            close(pipefd[0]);
            exit(0);
        }
        // 父进程
        close(pipefd[0]); // 关闭不必要的fd
        v.push_back(Pipefd(pipefd[1], pid));
    }
}

void Showboard(int &command)
{

    cout << "******************************************" << endl;
    cout << "******************************************" << endl;
    cout << "********0.Print       1.Mysql ************" << endl;
    cout << "********2.Vs          3.exit  ************" << endl;
    cout << "******************************************" << endl;
    cout << "******************************************" << endl;
    cout<<"输入你想要执行的任务:";
    cin >> command;

}
void Ctrlprocess(vector<Pipefd> &v, int &command)
{
    Count%=COUNT;
    cout<<"现在执行的进程:"<<v[Count]._name<<"执行的命令是:"<<command<<endl;
    write(v[Count++].write_fd,&command,sizeof(int));

}
void Exitprocess(vector<Pipefd>& v)
{
for(auto e:v)
{
    close(e.write_fd);
}
for(auto e:v)
{
    waitpid(e._pid,nullptr,0);   
}

}
int main()
{
    vector<Pipefd> v;
    Create(v);
    int command;
    while (true)
    {
        Showboard(command);
        if (command == 3)
        {
            break;
        }
        if(command<0||command>2)
        {
            continue;
        }
        Ctrlprocess(v,command);
        sleep(1);
    }
    Exitprocess(v);

    return 0;
}

/*int main()
{

    vector<Pipefd> v;
    Create(v);
    while(true)
    {
        int command=0;
        int index=rand()%v.size();
        write(v[index].write_fd,&command,sizeof(int));
        sleep(1);

    }
    return 0;
}*/